
#include <stdio.h>
#include <stdarg.h>
#include "matrix.h"

/**
 * These macros are here to help you create tests more easily and keep them
 * clear.
 *
 * The basic idea with unit-testing is create a test function for every real
 * function and inside the test function declare some variables and execute the
 * function under test.
 *
 * Use the ASSERT_MACRO to verify correctness of values.
 */

/**
 * Evaluates b and continues if b is true.
 * If b is false, ends the test by returning false and prints a detailed
 * message about the failure.
 */
#define ASSERT_TRUE(b)                                                         \
do                                                                             \
{                                                                              \
	if( !(b) )                                                                 \
	{                                                                          \
		printf("\nAssertion failed at %s:%d %s\n",__FILE__,__LINE__,#b);  	   \
		return false;                                                          \
	}                                                                          \
} while (0)

/**
 * Macro used for running a test from the main function
 */
#define RUN_TEST(test)                                                         \
do                                                                             \
{                                                                              \
	printf("Running "#test"... ");                                             \
	if( test )                                                                 \
	{                                                                          \
		printf( "[OK]\n" );                                                    \
	}                                                                          \
} while(0)

Matrix initMatrix( int rows, int columns, ... )
{
	Matrix result = matrixCreate( rows, columns );
	if( result == NULL )
	{
		return NULL;
	}

	va_list vl;
	va_start( vl, columns );

	for( int r = 0; r < rows; ++r )
	{
		for( int c = 0; c < columns; ++c )
		{
			double real = va_arg(vl,double);
			double imaginary = va_arg(vl,double);
			matrixSet( result, r, c, complexCreate( real, imaginary ) );
		}
	}

	va_end( vl );

	return result;
}

#define ASSERT_VALID(c) ASSERT_TRUE( complexIsValid( (c) ) )
#define ASSERT_INVALID(c) ASSERT_TRUE( !complexIsValid( (c) ) )
#define ASSERT_NULL(b) ASSERT_TRUE( (b) == MATRIX_NULL_ARGUMENT )
#define ASSERT_SUCCESS(b) ASSERT_TRUE( (b) == MATRIX_SUCCESS )
#define ASSERT_MATRIX_EQUAL(A,B) ASSERT_TRUE( matrixIsEqual( (A), (B) ) )
#define ASSERT_MATRIX_NOT_EQUAL(A,B) ASSERT_TRUE( !matrixIsEqual( (A), (B) ) )
#define ASSERT_DIMENSIONS(b) ASSERT_TRUE( (b) == MATRIX_BAD_DIMENSIONS )
#define ASSERT_SINGULAR(b) ASSERT_TRUE( (b) == MATRIX_SINGULAR )
#define ASSERT_BOUNDS(b) ASSERT_TRUE( (b) == MATRIX_OUT_OF_BOUNDS )

bool testGetSet()
{
	Complex c = complexCreate( 0, 0 );
	ASSERT_INVALID( matrixGet( NULL, 2, 3 ) );
	ASSERT_NULL( matrixSet( NULL, 7, -4, c ) );

	Matrix m = matrixCreate( 17, 29 );
	ASSERT_INVALID( matrixGet( m, 0, -20 ) );
	ASSERT_INVALID( matrixGet( m, 0, 29 ) );
	ASSERT_INVALID( matrixGet( m, 0, 129 ) );
	ASSERT_INVALID( matrixGet( m, -20, 0 ) );
	ASSERT_INVALID( matrixGet( m, 17, 0 ) );
	ASSERT_INVALID( matrixGet( m, 123, 0 ) );
	ASSERT_INVALID( matrixGet( m, -20, -20 ) );
	ASSERT_INVALID( matrixGet( m, 17, 29 ) );
	ASSERT_INVALID( matrixGet( m, 123, 129 ) );
	ASSERT_TRUE( matrixSet( m, 0, -20, c ) == MATRIX_OUT_OF_BOUNDS );
	ASSERT_TRUE( matrixSet( m, 0, 29, c ) == MATRIX_OUT_OF_BOUNDS );
	ASSERT_TRUE( matrixSet( m, 0, 129, c ) == MATRIX_OUT_OF_BOUNDS );
	ASSERT_TRUE( matrixSet( m, -20, 0, c ) == MATRIX_OUT_OF_BOUNDS );
	ASSERT_TRUE( matrixSet( m, 17, 0, c ) == MATRIX_OUT_OF_BOUNDS );
	ASSERT_TRUE( matrixSet( m, 123, 0, c ) == MATRIX_OUT_OF_BOUNDS );
	ASSERT_TRUE( matrixSet( m, -20, -20, c ) == MATRIX_OUT_OF_BOUNDS );
	ASSERT_TRUE( matrixSet( m, 17, 29, c ) == MATRIX_OUT_OF_BOUNDS );
	ASSERT_TRUE( matrixSet( m, 123, 129, c ) == MATRIX_OUT_OF_BOUNDS );

	int sign = 1;
	for( int row = 0; row < m->rows; ++row )
	{
		for( int column = 0; column < m->columns; ++column )
		{
			c = complexCreate( row * sign, column * -1 * sign );
			ASSERT_SUCCESS( matrixSet( m, row, column, c ) );
			ASSERT_TRUE( complexIsEqual( matrixGet(m,row,column), c ) );
			sign *= -1;
		}
	}

	matrixDestroy( m );

	return true;
}

bool testIsEqual()
{
	Matrix m1 = matrixCreate( 6, 2 );
	Matrix m2 = initMatrix( 3, 3,
			 13.5086,  39.2154,   8.3012,   8.2644,  16.4205,   4.3866,
			  5.8499,  12.6278,  -7.8783,  33.0417, -19.6003, -31.1269,
			  9.2588,  46.8545,   1.3925,  -3.0251,   0.0176,  13.0428);
	Matrix m3 = initMatrix( 3, 3,
			 13.5086,  39.2154,   8.3012,   8.2644,  16.4205,   4.3866,
			  5.8499,  12.6278,  -7.8783,  33.0417, -19.6003, -31.1269,
			  9.2588,  46.8545,   1.3925,  -3.0251,   0.0176,  13.0428);
	Matrix m4 = initMatrix( 3, 3,
			 13.5086,  39.2154,   8.3012,   8.2644,  16.4205,   4.3866,
			 -5.8499,  12.6278,  -7.8783,  33.0417, -19.6003, -31.1269,
			  9.2588,  46.8545,   1.3925,  -3.0251,   0.0176,  13.0428);

	ASSERT_MATRIX_EQUAL( NULL,NULL );
	ASSERT_MATRIX_NOT_EQUAL( m1,NULL );
	ASSERT_MATRIX_NOT_EQUAL( NULL,m1 );
	ASSERT_MATRIX_EQUAL( m1,m1 );
	ASSERT_MATRIX_NOT_EQUAL( m1,m2 );
	ASSERT_MATRIX_EQUAL( m2,m3 );
	ASSERT_MATRIX_EQUAL( m3,m2 );
	ASSERT_MATRIX_NOT_EQUAL( m3,m4 );
	ASSERT_MATRIX_NOT_EQUAL( m4,m3 );

	matrixDestroy( m1 );
	matrixDestroy( m2 );
	matrixDestroy( m3 );
	matrixDestroy( m4 );
	return true;
}

bool testCreate()
{
	Matrix m1 = matrixCreate( -1, 2 );
	Matrix m2 = matrixCreate( 1, -2 );
	Matrix m3 = matrixCreate( 6, 6 );
	ASSERT_MATRIX_NOT_EQUAL(m3,NULL);
	for (int i=0;i< 6;i++){
		for (int j=0;i<6;i++){
			ASSERT_TRUE(complexIsZero(matrixGet(m3,i,j)));
		}
	}
	Matrix m4 = matrixCreate(0,1);
	Matrix m5 = matrixCreate(1,0);
	ASSERT_MATRIX_EQUAL( m1,NULL );
	ASSERT_MATRIX_EQUAL( m2,NULL );
	ASSERT_MATRIX_EQUAL( m4,NULL );
	ASSERT_MATRIX_EQUAL( m5,NULL );
	matrixDestroy( m3 );
	return true;
}

bool testDestroy()
{
	matrixDestroy(NULL);
	return true;
}

bool testCreateUnit()
{
	Matrix m1 = matrixCreateUnit(6);
	ASSERT_MATRIX_NOT_EQUAL(m1,NULL);
	for (int i=0;i< 6;i++){
		for (int j=0;i<6;i++){
			if (i!=j) {
				ASSERT_TRUE(complexIsZero(matrixGet(m1,i,j)));
			}
			else {
				ASSERT_TRUE(complexIsEqual(matrixGet(m1,i,i),
										   complexCreate(1,0)));
			}
		}
	}
	Matrix m2 = matrixCreateUnit(-1);
	ASSERT_MATRIX_EQUAL(m2,NULL);
	Matrix m3 = matrixCreateUnit(0);
	ASSERT_MATRIX_EQUAL(m3,NULL);
	matrixDestroy(m1);
	return true;
}


bool testAdd()
{
	Matrix m1 = initMatrix( 3, 3,
		   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
			  5.0,  12.0,  -7.0,  33.0, -19.0, -31.0,
			  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	Matrix m2 = initMatrix( 3, 3,
			 15.5086,  39.2154,   8.3012,   8.2644,  16.4205,   4.3866,
			  5.8499,  12.6278,  -5.8783,  33.0417, -19.6003, 31.1269,
			  9.2588,  46.8545,   1.3925,  -3.0251,   2.0176,  13.0428);
	Matrix m3 = initMatrix( 3, 3,
			 16.5086,  41.2154,   10.3012,   16.2644,  32.4205,   8.4866,
			  10.8499,  24.6278,  -12.8783,  66.0417, -38.6003,   0.1269,
			  18.2588,  92.8545,   2.3925,  -6.0251,   2.0176,  26.0428);
	Matrix m4 = initMatrix( 3, 3,
		   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
			  5.0,  12.0,  -7.0,  33.0, -19.0, -31.0,
			  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	ASSERT_SUCCESS(matrixAdd(m2,m1));
	ASSERT_MATRIX_EQUAL(m1,m4);
	ASSERT_MATRIX_EQUAL(m3,m2);
	ASSERT_NULL(matrixAdd(m1,NULL));
	ASSERT_NULL(matrixAdd(NULL,m1));
	ASSERT_NULL(matrixAdd(NULL,NULL));
	Matrix m5 = matrixCreate(4,3);
	ASSERT_DIMENSIONS(matrixAdd(m1,m5));
	Matrix m6 = matrixCreate(3,4);
	ASSERT_DIMENSIONS(matrixAdd(m1,m6));
	matrixDestroy(m1);
	matrixDestroy(m2);
	matrixDestroy(m3);
	matrixDestroy(m4);
	matrixDestroy(m5);
	matrixDestroy(m6);
	return true;
}

bool testSubtract()
{
	Matrix m1 = initMatrix( 3, 3,
		   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
			  5.0,  12.0,  -7.0,  33.0, -19.0, -31.0,
			  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	Matrix m2 = initMatrix( 3, 3,
			 15.5086,  39.2154,   8.3012,   8.2644,  16.4205,   4.3866,
			  5.8499,  12.6278,  -5.8783,  33.0417, -19.6003, 31.1269,
			  32.2588, 26.8545,  11.3925,  -3.0251,   2.0176,  13.0428);
	Matrix m3 = initMatrix( 3, 3,
			 14.5086,  37.2154,    6.3012,   0.2644,   0.4205,   0.2866,
			  0.8499,   0.6278,    1.1217,   0.0417,   -0.6003,  62.1269,
			 23.2588,  -19.1455,  10.3925,   -0.0251,   2.0176,   0.0428);
	Matrix m4 = initMatrix( 3, 3,
		   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
			  5.0,  12.0,  -7.0,  33.0, -19.0, -31.0,
			  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	ASSERT_SUCCESS(matrixSubtract(m2,m1));
	ASSERT_MATRIX_EQUAL(m1,m4); //check to see that m1 hasn't changed
	ASSERT_MATRIX_EQUAL(m2,m3);
	ASSERT_NULL(matrixSubtract(m1,NULL));
	ASSERT_NULL(matrixSubtract(NULL,m1));
	ASSERT_NULL(matrixSubtract(NULL,NULL));
	Matrix m5 = matrixCreate(4,3);
	ASSERT_DIMENSIONS(matrixSubtract(m1,m5));
	Matrix m6 = matrixCreate(3,4);
	ASSERT_DIMENSIONS(matrixSubtract(m1,m6));
	matrixDestroy(m1);
	matrixDestroy(m2);
	matrixDestroy(m3);
	matrixDestroy(m4);
	matrixDestroy(m5);
	matrixDestroy(m6);
	return true;
}

bool testNegate()
{
	Matrix m1 = initMatrix( 3, 3,
			 -15.5086, -39.2154,   -8.3012,   -8.2644,  -16.4205,  -4.3866,
			 -5.8499,  -12.6278,    5.8783,  -33.0417,   19.6003, -31.1269,
			 -32.2588, -26.8545,  -11.3925,    3.0251,   -2.0176, -13.0428);
	Matrix m2 = initMatrix( 3, 3,
			 15.5086,  39.2154,   8.3012,   8.2644,  16.4205,   4.3866,
			  5.8499,  12.6278,  -5.8783,  33.0417, -19.6003, 31.1269,
			  32.2588, 26.8545,  11.3925,  -3.0251,   2.0176,  13.0428);
	ASSERT_SUCCESS(matrixNegate(m1));
	ASSERT_MATRIX_EQUAL(m1,m2);
	ASSERT_SUCCESS(matrixNegate(m1));
	ASSERT_SUCCESS(matrixNegate(m2));
	ASSERT_MATRIX_EQUAL(m1,m2);
	ASSERT_SUCCESS(matrixNegate(m2));
	ASSERT_MATRIX_NOT_EQUAL(m1,m2);
	ASSERT_NULL(matrixNegate(NULL));
	matrixDestroy(m1);
	matrixDestroy(m2);
	return true;
}

bool testMultiply1()
{
	Matrix m1 = initMatrix( 3, 3,
		   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
			  5.0,  12.0,  -7.0,  33.0, -19.0, -31.0,
			  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	Matrix m2;
	ASSERT_NULL(matrixMultiply(NULL,m1,&m2));
	ASSERT_NULL(matrixMultiply(m1,NULL,&m2));
	ASSERT_NULL(matrixMultiply(m1,m1,NULL));
	ASSERT_NULL(matrixMultiply(NULL,NULL,&m2));
	Matrix mUnit = matrixCreateUnit(3);
    ASSERT_SUCCESS(matrixMultiply(m1,mUnit,&m2));
	ASSERT_MATRIX_EQUAL(m1,m2);
	matrixDestroy(m2);
	Matrix m3 = matrixCreate(3,3);
	ASSERT_SUCCESS(matrixMultiply(m1,m3,&m2));
	ASSERT_MATRIX_EQUAL(m3,m2);
	Matrix m4 = matrixCreate(4,5);
	ASSERT_DIMENSIONS(matrixMultiply(m4,m3,&m2));
	Matrix m5 = matrixCreate(3,4);
	ASSERT_DIMENSIONS(matrixMultiply(m5,m3,&m2));
	matrixDestroy(m1);
	matrixDestroy(m2);
	matrixDestroy(m3);
	matrixDestroy(m4);
	matrixDestroy(m5);
	matrixDestroy(mUnit);
	return true;
}

bool testSwapRows()
{
	Matrix m1 = initMatrix( 3, 3,
		   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
			  5.0,  12.0,  -7.0,  33.0, -19.0, -31.0,
			  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	Matrix m2 = initMatrix( 3, 3,
			  5.0,  12.0,  -7.0,  33.0, -19.0, -31.0,
			  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
			  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	Matrix m3 = initMatrix( 3, 3,
		   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
			  5.0,  12.0,  -7.0,  33.0, -19.0, -31.0,
			  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	Matrix m4 = initMatrix( 3, 3,
			   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
				  5.0,  12.0,  -7.0,  33.0, -19.0, -31.0,
				  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	Matrix m5 = initMatrix( 3, 3,
			   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
				  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0,
				  5.0,  12.0,  -7.0,  33.0, -19.0, -31.0);
	ASSERT_SUCCESS(matrixSwapRows(m1,0,1));
	ASSERT_MATRIX_EQUAL(m1,m2);
	ASSERT_SUCCESS(matrixSwapRows(m2,1,0));
	ASSERT_MATRIX_EQUAL(m3,m2);
	ASSERT_SUCCESS(matrixSwapRows(m4,1,2));
	ASSERT_MATRIX_EQUAL(m5,m4);
	ASSERT_NULL(matrixSwapRows(NULL,-1,2));
	ASSERT_BOUNDS(matrixSwapRows(m1,3,2));
	ASSERT_BOUNDS(matrixSwapRows(m1,3,3));
	ASSERT_BOUNDS(matrixSwapRows(m1,2,3));
	ASSERT_BOUNDS(matrixSwapRows(m1,2,-3));
	ASSERT_BOUNDS(matrixSwapRows(m1,-1,2));
	matrixDestroy(m1);
	matrixDestroy(m2);
	matrixDestroy(m3);
	matrixDestroy(m4);
	matrixDestroy(m5);
	return true;
}

bool testMultiplyRowByScalar()
{
	Matrix m1 = initMatrix( 3, 3,
		   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
			  5.0,  12.0,  -7.0,  33.0, -19.0, -31.0,
			  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	Matrix m2 = initMatrix( 3, 3,
		   	  5.0,  10.0,    10.0,   40.0,  80.0,   20.5,
			  5.0,  12.0,  -7.0,  33.0, -19.0, -31.0,
			  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	ASSERT_SUCCESS(matrixMultiplyRowByScalar(m1,0,complexCreate(5,0)));
	ASSERT_MATRIX_EQUAL(m1,m2);
	ASSERT_NULL(matrixMultiplyRowByScalar(NULL,5,complexCreate(5,0)));
	ASSERT_BOUNDS(matrixMultiplyRowByScalar(m2,-1,complexCreate(5,0)));
	ASSERT_BOUNDS(matrixMultiplyRowByScalar(m2,-2,complexCreate(5,0)));
	ASSERT_BOUNDS(matrixMultiplyRowByScalar(m2,3,complexCreate(5,0)));
	ASSERT_BOUNDS(matrixMultiplyRowByScalar(m2,4,complexCreate(5,0)));
	matrixDestroy(m1);
	matrixDestroy(m2);
	return true;
}

bool testSubtractRow()
{
	Matrix m1 = initMatrix( 3, 3,
		   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
			  5.0,  12.0,  -7.0,  33.0, -19.0, -31.0,
			  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	Matrix m2 = initMatrix( 3, 3,
		   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
			  2.0,  6.0,  -13.0,   9.0, -67.0, -43.3,
			  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	ASSERT_SUCCESS(matrixSubtractRow(m1,1,0,complexCreate(3,0)));
	ASSERT_MATRIX_EQUAL(m1,m2);
	ASSERT_NULL(matrixSubtractRow(NULL,2,1,complexCreate(3,0)));
	ASSERT_BOUNDS(matrixSubtractRow(m1,3,1,complexCreate(3,0)));
	ASSERT_BOUNDS(matrixSubtractRow(m1,2,-1,complexCreate(3,0)));
	ASSERT_BOUNDS(matrixSubtractRow(m1,3,-1,complexCreate(3,0)));
	matrixDestroy(m1);
	matrixDestroy(m2);
	return true;
}

bool testInverse1()
{
	Matrix m1 = initMatrix( 3, 3,
		   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
			  5.0,  12.0,  -7.0,  33.0, -19.0, -31.0,
			  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	Matrix m2,m3;
	ASSERT_SUCCESS(matrixInverse(m1,&m2));
	matrixMultiply(m1,m2,&m3);
	Matrix mUnit = matrixCreateUnit(3);
	ASSERT_MATRIX_EQUAL(m3,mUnit);
	ASSERT_NULL(matrixInverse(NULL,&m2));
	ASSERT_NULL(matrixInverse(m1,NULL));
	ASSERT_NULL(matrixInverse(NULL,NULL));
	Matrix m4 = initMatrix( 3, 3,
		   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
		   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
			  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	ASSERT_SINGULAR(matrixInverse(m4,&m2));
	Matrix m5 = matrixCreate(3,4);
	ASSERT_DIMENSIONS(matrixInverse(m5,&m2));
	Matrix m6 = matrixCreate(4,3);
	ASSERT_DIMENSIONS(matrixInverse(m6,&m2));
	matrixDestroy(m1);
	matrixDestroy(m2);
	matrixDestroy(m3);
	matrixDestroy(m4);
	matrixDestroy(m5);
	matrixDestroy(m6);
	matrixDestroy(mUnit);
	return true;
}

bool testSolveEquationSystem1()
{
	Matrix m1 = initMatrix( 3, 3,
			   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
				  5.0,  12.0,  -7.0,  33.0, -19.0, -31.0,
				  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	Matrix m2 =  initMatrix( 3, 1,
		   	  1.0,  2.0,
			  5.0,  12.0,
			  9.0,  46.0);
	Matrix m3;
	ASSERT_NULL(matrixSolveEquationSystem(m1,m2,NULL));
	ASSERT_NULL(matrixSolveEquationSystem(m1,NULL,&m3));
	ASSERT_NULL(matrixSolveEquationSystem(NULL,m2,&m3));
	ASSERT_NULL(matrixSolveEquationSystem(m2,NULL,NULL));
	ASSERT_NULL(matrixSolveEquationSystem(NULL,m1,NULL));
	ASSERT_NULL(matrixSolveEquationSystem(NULL,NULL,&m3));
	ASSERT_NULL(matrixSolveEquationSystem(NULL,NULL,NULL));
	Matrix m4 = matrixCreate(4,3);
	ASSERT_DIMENSIONS(matrixSolveEquationSystem(m4,m2,&m3));
	Matrix m5 = matrixCreate(3,2);
	ASSERT_DIMENSIONS(matrixSolveEquationSystem(m1,m5,&m3));
	Matrix m6 = matrixCreate(4,1);
	ASSERT_DIMENSIONS(matrixSolveEquationSystem(m1,m6,&m3));
	Matrix m7 = initMatrix( 3, 3,
		   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
		   	  1.0,  2.0,    2.0,   8.0,  16.0,   4.1,
			  9.0,  46.0,   1.0,  -3.0,   0.0,  13.0);
	ASSERT_SINGULAR(matrixSolveEquationSystem(m7,m2,&m3));
	ASSERT_SUCCESS(matrixSolveEquationSystem(m1,m2,&m3));
	Matrix m8;
	matrixMultiply(m1,m3,&m8);
	ASSERT_MATRIX_EQUAL(m8,m2);
	matrixDestroy(m1);
	matrixDestroy(m2);
	matrixDestroy(m3);
	matrixDestroy(m4);
	matrixDestroy(m5);
	matrixDestroy(m6);
	matrixDestroy(m7);
	matrixDestroy(m8);
	return true;
}

int main()
{
	RUN_TEST( testGetSet() );
	RUN_TEST( testIsEqual() );
	RUN_TEST( testCreate() );
	RUN_TEST( testDestroy() );
	RUN_TEST( testCreateUnit() );
	RUN_TEST( testAdd() );
	RUN_TEST( testSubtract());
	RUN_TEST( testNegate());
	RUN_TEST( testMultiply1());
	RUN_TEST( testSwapRows());
	RUN_TEST( testMultiplyRowByScalar() );
	RUN_TEST( testSubtractRow() );
	RUN_TEST( testInverse1() );
	RUN_TEST( testSolveEquationSystem1() );
	return 0;
}

